package com.ll.utils;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;

/**
 * Created with IntelliJ IDEA.
 * User: zc
 * Date: 13-12-17
 * Time: 下午5:44
 * To change this template use File | Settings | File Templates.
 */
public class XmlUtil {

    /**
     * 取得xml根元素
     *
     * @param doc
     * @return 根元素
     */
    public static Element getRootElement(Document doc) {
        return doc.getRootElement();
    }

    /**
     * 取得xml
     *
     * @param fileName 文件名
     * @return xml
     * @throws MalformedURLException
     * @throws DocumentException
     */
    public static Document read(String fileName) throws MalformedURLException, DocumentException {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream is = loader.getResourceAsStream(fileName);
        SAXReader reader = new SAXReader();
        Document document = reader.read(is);
        return document;
    }

    /**
     * 取得xml
     *
     * @param file 文件
     * @return xml
     * @throws MalformedURLException
     * @throws DocumentException
     */
    public static Document read(File file) throws MalformedURLException, DocumentException {

        SAXReader reader = new SAXReader();
        Document document = reader.read(file);
        return document;
    }

    /**
     * 根据xpath 查询节点中的内容
     *
     * @param doc   文档
     * @param xpath xpath
     * @return 内容
     */
    public static String getElementText(Document doc, String xpath) {
        String text = "";
        Node node = doc.selectSingleNode(xpath);
        if (node != null) {
            text = node.getText();
        }
        return text;
    }

    /**
     * 根据xpath 查询节点数
     *
     * @paramdoc   文档
     * @param xpath xpath
     * @return 内容
     */
    public static int getElementCount(String fileName, String xpath) {
        String text = "";
        Document doc = null;
        try {
            doc = read(fileName);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return doc.selectNodes(xpath).size();
    }

    /**
     * 根据xpath 查询属性中的内容
     *
     * @param doc       文档
     * @param xpath     xpath
     * @param attribute 属性
     * @return 内容
     */
    public static String getAttributeText(Document doc, String xpath, String attribute) {
        String text = "";
        Element node = (Element) doc.selectSingleNode(xpath);
        if (node != null) {
            text = node.attributeValue(attribute);
        }
        return text;
    }

    /**
     * 通过xpath读取xml文件中的某个节点内容
     *
     * @param fileName xml文件名
     * @param xpath    xpath
     * @return 节点内容
     */
    public static String readXmlElementText(String fileName, String xpath) {
        Document doc = null;
        String text = "";
        try {
            doc = read(fileName);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        text = getElementText(doc, xpath);
        return text;
    }

    /**
     * 通过xpath读取xml文件中的某个节点内容
     *
     * @param xml xml
     * @param xpath    xpath
     * @return 节点内容
     */
    public static String readXmlElementTextByXml(String xml, String xpath) {
        Document doc = null;
        String text = "";
        try {
            //创建一个新的字符串
            StringReader read = new StringReader(xml);
            //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
            InputSource source = new InputSource(read);
            //创建一个新的SAXBuilder
            SAXReader reader = new SAXReader();
            doc = reader.read(source);
        }  catch (DocumentException e) {
            e.printStackTrace();
        }
        text = getElementText(doc, xpath);
        return text;
    }

    /**
     * 通过xpath读取xml文件中的某个节点属性
     *
     * @param fileName  xml文件名
     * @param xpath     xpath
     * @param attribute 属性
     * @return 节点内容
     */
    public static String readXmlAttributeText(String fileName, String xpath, String attribute) {
        Document doc = null;
        String text = "";
        try {
            doc = read(fileName);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        text = getAttributeText(doc, xpath, attribute);
        return text;
    }

    /**
     *
     * 功能: xml文件转换成cls类型的bean<br/>
     * 说明: <br/>
     *
     * @author yubin
     * @param file
     * @param cls
     * @return
     * @return T
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T xml2Bean(File file, Class<T> cls) {
        JAXBContext jaxbContext;
        T t = null;
        try {
            jaxbContext = JAXBContext.newInstance(cls);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            t = (T) jaxbUnmarshaller.unmarshal(file);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return t;
    }

    /**
     *
     * 功能: xml文件流转换成cls类型的bean<br/>
     * 说明: <br/>
     *
     * @author yubin
     * @param is 输入流
     * @param cls
     * @return
     * @return T
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T xml2Bean(InputStream is, Class<T> cls) {
        JAXBContext jaxbContext;
        T t = null;
        try {
            jaxbContext = JAXBContext.newInstance(cls);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            t = (T) jaxbUnmarshaller.unmarshal(is);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return t;
    }
}
